<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        function MyPromise(executor){
            var self = this;
            self.status = 'pending';//待定
            self.resolveValue = null;
            self.rejectValue = null;
            self.ResolveCallBackList = [];//注册成功的函数
            self.RejectCallBackList = [];//注册失败的函数
            function resolve(res){
                if(self.status === 'pending'){
                    self.status = 'Fulfilled';//完成
                    self.resolveValue = res;
                    self.ResolveCallBackList.forEach(function(ele){
                        ele();
                    });
                }
            }
            function reject(rej){
                if(self.status === 'pending'){
                    self.status = 'Rejected';//拒绝
                    self.rejectValue = rej;
                    self.RejectCallBackList.forEach(function(ele){
                        ele();
                    });
                }
            }
            //
            try {
                executor(resolve,reject);
            } catch (error) {
                reject(error)
            }
        };

        //return为一个新的promise对象
        function ResolutionReturnPromise(nextPromise,returnValue,res,rej){
            if(returnValue instanceof MyPromise){
                //Promise对象
                returnValue.then(function(val){
                    res(val);
                },function(response){
                    rej(response);
                })
            }else {
                res(returnValue)
            }
        }

        MyPromise.prototype.then = function(onFulfilled,onRejected){
            if(!onFulfilled){
                onFulfilled = function(val){
                    return val;
                }
            }
            if(!onRejected){
                onRejected = function(rej){
                    return rej;
                }
            }
            var self = this;
            //链式编写
            var nextPromise = new MyPromise(function(res,rej){

                if(self.status === 'Fulfilled'){
                    setTimeout(() => {
                        try {
                            // var nextResolveValue =  onFulfilled(self.resolveValue);
                            // res(nextResolveValue);
                            var nextResolveValue =  onFulfilled(self.resolveValue);
                            ResolutionReturnPromise(nextResolveValue,nextResolveValue,res,rej);
                        } catch (error) {
                            rej(error)
                        }
                    }, 0);
                }
                if(self.status === 'Rejected'){
                    setTimeout(() => {
                        try {
                            var nextRejectValue = onRejected(self.rejectValue)
                            // rej(nextRejectValue);
                            ResolutionReturnPromise(nextRejectValue,nextRejectValue,res,rej);
                        } catch (error) {
                            rej(error)
                        }
                    }, 0);
                }
                if(self.status === 'pending'){
                    self.ResolveCallBackList.push(function(){
                        setTimeout(() => {
                            try {
                                // var nextResolveValue =  onFulfilled(self.resolveValue);
                                // res(nextResolveValue);
                                var nextResolveValue =  onFulfilled(self.resolveValue);
                                ResolutionReturnPromise(nextResolveValue,nextResolveValue,res,rej);
                            } catch (error) {
                                rej(e)
                            }
                        }, 0);
                        
                    });
                    self.RejectCallBackList.push(function(){
                        setTimeout(() => {
                            try {
                                // var nextRejectValue = onRejected(self.rejectValue)
                                // rej(nextRejectValue);
                                var nextRejectValue = onRejected(self.rejectValue)
                                ResolutionReturnPromise(nextRejectValue,nextRejectValue,res,rej);
                            } catch (error) {
                                rej(error)
                            }
                        }, 0);
                    })
                }
            })
            
            return nextPromise;
        }

        //异步链式操作
        let p1 = new MyPromise((res,rej)=>{
            res(1);
        });
        p1.then((val)=>{
            console.log(val,'ok');
            return new MyPromise((res,rej)=>{
                rej(0)
            })
        },(response)=>{
            console.log(response,'no')
        }).then(()=>{},(response)=>{
            console.log(response,'no')
        });
    </script>
</body>
</html>